package leoner.javascript;

import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class BeanFilter {
	private static Log log = LogFactory.getLog(BeanFilter.class);
	private static Invocable inv;
	static{
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine engine = manager.getEngineByName("javascript");
		engine.put("log", log);
		Reader reader = new InputStreamReader(BeanFilter.class.getResourceAsStream("BeanFilter2.js"));
		try {
			engine.eval(reader);
		} catch (ScriptException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		inv = (Invocable)engine;
	}
	/**
	 * @param args
	 * 没有优化性能统计1000次1312，1313,1297,1281,1313
	 * 优化了对象只取属性,通过 BeanFilter.class.getDeclaredFields();执行1000次
	 * 750，750，735，765，734
	 * 
	 */
	
	public static void main(String[] args) throws ScriptException, NoSuchMethodException {

		
		List<Person> persons = new ArrayList<Person>();
		for(int i=0;i<1000;i++){
			persons.add(getPerson(i));
		}
//		List<String> ss = new ArrayList<String>();
//		ss.add("<abc>");
//		System.out.println(ss);
		System.out.println(persons.get(0));
		filter(persons);
		//testProifle(persons);
		System.out.println(persons.get(0));
//		Map map = new HashMap();
//		map.put("haha", getPerson(2));
		
//		System.out.println(persons.get(6));
//		System.out.println(map);
		
	}
	/**
	 * @param args
	 */
	public static  void testGetAttr(){
//		BeanFilter[0].
		Field[] fs = BeanFilter.class.getDeclaredFields();
		System.out.println(fs.length);
		for(Field f : fs){
			
			System.out.println(f.getName());
		}
	}
	public static void testProifle(Object o){
		long s = System.currentTimeMillis();
		try {
			inv.invokeFunction("testGetObjAttr2", o);
		} catch (Exception e) {
			log.error("filter error");
			e.printStackTrace();
		}
		long e = System.currentTimeMillis();
		System.out.println((e-s)+"s");
	}
	public  static void filter(Object o){
		long s = System.currentTimeMillis();
		try {
			inv.invokeFunction("filterString", o);
		} catch (Exception e) {
			log.error("filter error");
			e.printStackTrace();
		}
		long e = System.currentTimeMillis();
		System.out.println((e-s)+"s");
	}
	public static Person getPerson(int id){
		Person person = new Person();
		person.setName("<name>"+id);
		Address addr = new Address();
		addr.setHome("<home>"+id);
		addr.setWork("<work>"+id);
		person.setAddress(addr);
		Food food = new Food();
		food.setName("<food>"+id);
		Food[] foods = new Food[1];
		foods[0] = food;
		person.setFoods(foods);
		return person;
	}
	static class Food{
		private String name;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
	}
	static class Person{
		private String name;
		private int age;
		private Address address;
		private Food[] foods;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public int getAge() {
			return age;
		}
		public void setAge(int age) {
			this.age = age;
		}
		
		public Address getAddress() {
			return address;
		}
		public void setAddress(Address address) {
			this.address = address;
		}
		
		public Food[] getFoods() {
			return foods;
		}
		public void setFoods(Food[] foods) {
			this.foods = foods;
		}
		public String printArray(Food[] foods){
			if(null == foods)return "";
			StringBuilder sb = new StringBuilder();
			for(Food food : foods){
				sb.append("food:"+food.name);
			}
			return sb.toString();
		}
		@Override
		public String toString(){
			return "name:"+name+",age:"+age+"---address:"+address.toString()+"foods:"+printArray(foods);
		}
		
	}
	static class Address{
		private String home;
		private String work;
		public String getHome() {
			return home;
		}
		public void setHome(String home) {
			this.home = home;
		}
		public String getWork() {
			return work;
		}
		public void setWork(String work) {
			this.work = work;
		}
		@Override
		public String toString(){
			return "home:"+home+",work:"+work;
		}
	}

}
